package com.perceptivesoftware.licensing.client;

import java.util.List;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.perceptivesoftware.licensing.client.common.PerceptiveLogoSplitButton;
import com.perceptivesoftware.licensing.client.common.util.NPAction;
import com.perceptivesoftware.licensing.client.common.util.NPType;
import com.perceptivesoftware.licensing.client.dialogs.about.AboutDialog;
import com.perceptivesoftware.licensing.client.dialogs.systemparm.SystemEmailHostDialog;
import com.perceptivesoftware.licensing.client.dialogs.useradmin.UserAdminstrationDialog;
import com.perceptivesoftware.licensing.client.dto.UserInitialDTO;
import com.perceptivesoftware.licensing.client.dto.VideoDTO;
import com.perceptivesoftware.licensing.client.views.mostrecent.RecentVideosPanel;

class LicensingViewport extends Viewport implements LicensingViewportListener
{

	private final PerceptiveUISession session = PerceptiveUISession.getInstance();
	private final RecentVideosPanel recentVideos = new RecentVideosPanel();

	private PerceptiveLogoSplitButton perceptiveButton;
	private Button adminButton;

	private MenuItem aboutMenuItem;
	private MenuItem getAllVideosMenuItem;

	private MenuItem securityMenuItem;
	private MenuItem systemEmailHostItem;

	public LicensingViewport()
	{
		setId("LicensingViewPort");
		setLayoutOnChange(true);
		setMonitorWindowResize(true);
		setupViewport();
		final HandlerRegistration windowClosingHandler = Window.addWindowClosingHandler(new ClosingHandler() {

			@Override
			public void onWindowClosing(final ClosingEvent event)
			{
				event.setMessage("CLICK CANCEL, then use the logoff button to properly log off.");

			}
		});
		final HandlerRegistration closeHandler = Window.addCloseHandler(new CloseHandler<Window>() {

			@Override
			public void onClose(final CloseEvent<Window> event)
			{
				session.requestLogoff(false);
			}
		});
		session.setWindowCloseListenerRegistrations(windowClosingHandler, closeHandler);
	}

	public void setData(final UserInitialDTO userInitialDTO, final boolean isInitial)
	{
		session.setUserInitialDTO(userInitialDTO);
		enableDisableButtons();
		recentVideos.loadData();
	}

	private void enableDisableButtons()
	{
		securityMenuItem.setEnabled(session.hasPermission(NPType.ADMIN, NPAction.MANAGE_SECURITY));
		adminButton.setVisible(session.hasPermission(NPType.ADMIN, NPAction.MANAGE_SECURITY));
	}

	private void setupViewport()
	{
		setLayout(new FitLayout());

		final ContentPanel topContentPanel = new ContentPanel();
		topContentPanel.setLayout(new FitLayout());
		final ContentPanel cp = new ContentPanel();
		cp.setLayout(new FitLayout());
		cp.setHeaderVisible(false);
		cp.setTopComponent(buildToolBar());
		cp.add(recentVideos);
		topContentPanel.add(cp);

		// Get the Image Logo
		final AbstractImagePrototype image = IconHelper.create("perceptive-header-image");

		final LayoutContainer lc = new LayoutContainer();
		lc.setHeight(80);
		// lc.setAutoWidth(true);
		lc.setLayout(new FitLayout());
		lc.add(image.createImage());
		topContentPanel.setTopComponent(lc);
		topContentPanel.setHeaderVisible(false);

		add(topContentPanel);
	}

	private PerceptiveLogoSplitButton buildPerceptiveButton()
	{
		final PerceptiveLogoSplitButton perceptiveBtn = new PerceptiveLogoSplitButton();

		final Menu perceptiveMenu = new Menu();
		perceptiveBtn.setMenu(perceptiveMenu);

		final MenuItem openAdminHelpItem = new MenuItem("Open Admin Guide");
		openAdminHelpItem.setIconStyle("perceptive-icon-configure");
		openAdminHelpItem.addSelectionListener(new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(MenuEvent ce)
			{
				final String url = Window.Location.getPath() + "help/PERCEPTIVELICENSING-1_0_ADMIN_GUIDE.pdf";
				Window.open(url, "", "");
			}
		});
		perceptiveMenu.add(openAdminHelpItem);

		aboutMenuItem = new MenuItem("About Licensing");
		aboutMenuItem.setIconStyle("perceptive-icon-history");
		aboutMenuItem.addSelectionListener(new SelectionListener<MenuEvent>() {
			@Override
			public void componentSelected(final MenuEvent ce)
			{
				(new AboutDialog()).show();
			}
		});
		perceptiveMenu.add(aboutMenuItem);

		return perceptiveBtn;
	}

	private void buildAdminButton()
	{
		adminButton = new Button();
		adminButton.setText("Administration");
		adminButton.setIconStyle("perceptive-icon-configure");

		final Menu administrationMenu = new Menu();
		adminButton.setMenu(administrationMenu);

		securityMenuItem = new MenuItem("User");
		securityMenuItem.setIconStyle("perceptive-icon-privileges");
		securityMenuItem.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(final MenuEvent ce)
			{
				final UserAdminstrationDialog uad = new UserAdminstrationDialog();
				uad.addListener(Events.Hide, new Listener<BaseEvent>() {

					@Override
					public void handleEvent(final BaseEvent be)
					{
						loadUserDTO();
					}
				});
				uad.show();
			}
		});
		administrationMenu.add(securityMenuItem);

		systemEmailHostItem = new MenuItem("System Email");
		systemEmailHostItem.setIconStyle("perceptive-system-email");
		systemEmailHostItem.addSelectionListener(new SelectionListener<MenuEvent>() {

			@Override
			public void componentSelected(final MenuEvent ce)
			{
				final SystemEmailHostDialog sehd = new SystemEmailHostDialog();
				sehd.show();
			}
		});
		administrationMenu.add(systemEmailHostItem);

	}

	private ToolBar buildToolBar()
	{

		final ToolBar toolBar = new ToolBar();
		perceptiveButton = buildPerceptiveButton();
		toolBar.add(perceptiveButton);

		Button twistageButton = new Button("Get Videos");
		twistageButton.setIconStyle("perceptive-icon-logout");
		twistageButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(final ButtonEvent ce)
			{
				LicensingRPCFactory.getTwistageService(true).getAllVideos(new LicensingAsyncCallback<List<VideoDTO>>() {

					@Override
					public void onSuccess(final List<VideoDTO> result)
					{
						//do nothing
					}
				});
			}
		});
		toolBar.add(twistageButton);

		toolBar.add(new FillToolItem());

		buildAdminButton();
		toolBar.add(adminButton);

		final Button logoutButton = new Button("Logout");
		logoutButton.setIconStyle("perceptive-icon-logout");
		toolBar.add(logoutButton);
		logoutButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(final ButtonEvent ce)
			{
				session.requestLogoff(false);
			}
		});
		return toolBar;
	}

	@Override
	public void loadUserDTO()
	{
		LicensingRPCFactory.getSessionService(true).loadUserDTO(session.getSessionID(), new UserInitialDTOReturnAsyncCallback(false));
	}

	void initialLogon()
	{
		LicensingRPCFactory.getSessionService(true).initialLogon(new UserInitialDTOReturnAsyncCallback(true));
	}

	private class UserInitialDTOReturnAsyncCallback implements AsyncCallback<UserInitialDTO>
	{

		private final boolean isInitial;

		private UserInitialDTOReturnAsyncCallback(final boolean isInitial)
		{
			this.isInitial = isInitial;
		}

		@Override
		public void onSuccess(final UserInitialDTO result)
		{
			if (result.getErrorMessage() != null)
			{
				MessageBox.alert("Logon", result.getErrorMessage(), new Listener<MessageBoxEvent>() {

					@Override
					public void handleEvent(final MessageBoxEvent be)
					{
						session.redirectToLogoffPage();
					}
				});
			}
			else
			{
				setData(result, isInitial);
				if (isInitial)
				{
					session.startHeartbeatTimer();
				}
			}
		}

		@Override
		public void onFailure(final Throwable caught)
		{
			MessageBox.alert("Logon", "Unable to retrieve login information", new Listener<MessageBoxEvent>() {

				@Override
				public void handleEvent(final MessageBoxEvent be)
				{
					session.redirectToLogoffPage();
				}
			});
		}
	}

}
